package com.oneinlet


/**
 * Created by WangZiHe on 2018/5/13
 * QQ/WeChat:648830605
 * QQ-Group:368512253
 * Blog:www.520code.net
 * Github:https://github.com/yancheng199287
 */
object YCAssert {

    /**
     * 判断当前表达式是否为真，如果为假(false)，抛出异常，显示你的自定义错误消息
     * @param expression 表达式 返回结果 true false
     * @param message 自定义错误消息
     * */
    fun isTrue(expression: Boolean, message: String) {
        if (!expression) {
            throw IllegalArgumentException(message)
        }
    }

    /**
     * 判断当前表达式是否为真，如果为假(false)，抛出异常
     * @param expression 表达式 返回结果 true false
     * */
    fun isTrue(expression: Boolean) {
        isTrue(expression, "[断言失败] - 这个表达式必须为true")
    }

    /**
     * 判断当前对象是否为null，如果不为null，抛出异常，显示自定义错误消息
     * @param any 任意一个对象
     * @param message 自定义错误消息
     * */
    fun isNull(any: Any?, message: String) {
        if (any != null) {
            throw IllegalArgumentException(message)
        }
    }

    /**
     * 判断当前对象是否为null，如果不为null，抛出异常
     * @param any 任意一个对象
     * */
    fun isNull(any: Any?) {
        isNull(any, "[断言失败] - 这个对象参数必须是null")
    }

    /**
     * 判断当前对象是否不为null，如果为null，抛出异常，显示自定义错误消息
     * @param any 任意一个对象
     * @param message 自定义错误消息
     * */
    fun notNull(any: Any?, message: String) {
        if (any == null) {
            throw IllegalArgumentException(message)
        }
    }

    /**
     * 判断当前对象是否不为null，如果为null，抛出异常
     * @param any 任意一个对象
     * */
    fun notNull(any: Any?) {
        notNull(any, "[断言失败] - 这个参数是必须的; 它不能为null")
    }

    /**
     * 判断当前字符串不为null，且 有长度大于0，如果条件不成立，抛出自定义异常消息
     * @param text  目标字符串
     * @param message 自定义错误消息
     * */
    fun hasLength(text: String?, message: String) {
        if (!YCString.hasLength(text)) {
            throw IllegalArgumentException(message)
        }
    }

    /**
     * 判断当前字符串不为null，且 有长度大于0，如果条件不成立，抛出异常
     * @param text  目标字符串
     * */
    fun hasLength(text: String) {
        hasLength(text, "[断言失败] - 这个字符串必须有长度值; 它不能是 null 或者 空")
    }

    /**
     * 判断当前字符串是否有字符内容，首先不为null且长度大于0，而且不能是空格
     * @param text  目标字符串
     * @param message 自定义错误消息
     * */
    fun hasText(text: String, message: String) {
        if (!YCString.hasText(text)) {
            throw IllegalArgumentException(message)
        }
    }

    /**
     * 判断当前字符串是否有字符内容，首先不为null且长度大于0，而且不能是空格
     * @param text  目标字符串
     * */
    fun hasText(text: String) {
        hasText(text, "[断言失败] - 这个字符串必须包含内容文本; 它不能为null, ‘’/空, or 空格")
    }

    /**
     * 判断目标字符串是否不包含搜索字符串内容
     * @param textToSearch  搜索字符串
     * @param substring  目标字符串
     * @param message  报错消息
     * */
    fun doesNotContain(textToSearch: String, substring: String, message: String) {
        if (YCString.hasLength(textToSearch) && YCString.hasLength(substring) && textToSearch.indexOf(substring) != -1) {
            throw IllegalArgumentException(message)
        }
    }

    /**
     * 判断目标字符串是否不包含搜索字符串内容
     * @param textToSearch  搜索字符串
     * @param substring  目标字符串
     * @param message  报错消息
     * */
    fun doesNotContain(textToSearch: String, substring: String) {
        doesNotContain(textToSearch, substring, "[断言失败] - 这个字符串没有包含这个字符串：[$substring]")
    }

    /**
     * 判断目标集合是否为空或者size==0
     * @param textToSearch  搜索字符串
     * @param substring  目标字符串
     * @param message  报错消息
     * */
    fun notEmpty(array: Array<Any>?, message: String) {
        if (array == null || array.size == 0) {
            throw IllegalArgumentException(message)
        }
    }

    /**
     * 判断目标集合/数组是否为null或者 size==0 如果是则抛出异常
     * @param array  集合 / 数组
     * */
    fun notEmpty(array: Array<Any>) {
        notEmpty(array, "[断言失败] - 这个数组不能为空：它至少包含一个元素")
    }

    /**
     * 判断目标集合/数组的所有元素皆不为null 如果元素有一个null则抛出异常
     * @param array  集合 / 数组
     * @param message 异常消息
     * */
    fun noNullElements(array: Array<Any>?, message: String) {
        if (array != null) {
            for (i in array.indices) {
                if (array[i] == null) {
                    throw IllegalArgumentException(message)
                }
            }
        }

    }

    /**
     * 判断目标集合/数组的所有元素皆不为null 如果元素有一个null则抛出异常
     * @param array  集合 / 数组
     * */
    fun noNullElements(array: Array<Any>) {
        noNullElements(array, "[断言失败] - 这个数组不能包含null元素")
    }

    /**
     * 判断目标集合不为null 且 size>0 否则抛出异常
     * @param collection  集合
     * */
    fun notEmpty(collection: Collection<*>, message: String) {
        if (YCollections.isEmpty(collection)) {
            throw IllegalArgumentException(message)
        }
    }

    /**
     * 判断目标集合/数组的所有元素皆不为null 且 size==0  抛出异常
     * @param collection  集合
     * */
    fun notEmpty(collection: Collection<*>) {
        notEmpty(collection, "[断言失败] - 这个集合不能为空: 它至少包含一个元素")
    }

    /**
     * 判断目标集合/数组的所有元素皆不为null 且 size==0  抛出异常
     * @param collection  集合
     * */
    fun notEmpty(map: Map<*, *>, message: String) {
        if (YCollections.isEmpty(map)) {
            throw IllegalArgumentException(message)
        }
    }

    /**
     *
     * */
    fun notEmpty(map: Map<*, *>) {
        notEmpty(map, "[断言失败] - 这个map不能为空; 它至少包含一个entry")
    }

    /**
     * 判断 对象是否是这个类的实例
     * @param type 类
     * @param obj 对象
     * */
    fun isInstanceOf(clazz: Class<*>, obj: Any) {
        isInstanceOf(clazz, obj, "")
    }

    /**
     * 判断 obj对象是否是这个type类的实例
     * @param type 类
     * @param obj 对象
     * @param message 抛出自定义异常消息
     * */
    fun isInstanceOf(type: Class<*>, obj: Any?, message: String) {
        notNull(type, "类型检查，不能为null")
        if (!type.isInstance(obj)) {
            throw IllegalArgumentException(message + "这个类的对象 [" + (if (obj != null) obj.javaClass.name else "null") + "] 必须是这个类型 " + type)
        }
    }

    /**
     * 判断 subType是否是superType的子类或接口
     * @param type 类
     * @param obj 对象
     * */
    fun isAssignable(superType: Class<*>, subType: Class<*>) {
        isAssignable(superType, subType, "")
    }

    /**
     * 判断 subType是否是superType的子类或接口
     * @param type 类
     * @param obj 对象
     * @param message 抛出自定义异常消息
     * */
    fun isAssignable(superType: Class<*>, subType: Class<*>?, message: String) {
        notNull(superType, "类型检查，不能为null")
        if (subType == null || !superType.isAssignableFrom(subType)) {
            throw IllegalArgumentException("$message$subType 不可分配给 $superType")
        }
    }

}